package ecweb.service.impl;

import java.util.LinkedList;
import java.util.List;

import ecweb.dal.DatabaseSession;
import ecweb.dao.ICartDao;
import ecweb.dao.IGoodDao;
import ecweb.dao.impl.CartDao;
import ecweb.dao.impl.GoodDao;
import ecweb.domain.CartItem;
import ecweb.domain.GoodItem;
import ecweb.domain.dto.TCartItemDetail;
import ecweb.domain.dto.TGoodItemAndQuantity;
import ecweb.exception.DatabaseException;
import ecweb.service.ICartService;
import util.lang.RefValue;

public class CartService implements ICartService {
	
	private ICartDao cartDao = new CartDao();
	private IGoodDao goodDao=new GoodDao();

	@Override
	public int getQuantity(long userId, long goodId) throws DatabaseException {
		try (DatabaseSession dbses = new DatabaseSession()) {
			int currentQuantity = cartDao.getQuantity(dbses, userId, goodId);
			if (currentQuantity < 0)
				return 0;
			return currentQuantity;
		}
	}

	@Override
	public void subQuantity(long userId, List<TGoodItemAndQuantity> goodItemAndQuantityList) throws DatabaseException {
		
		try (DatabaseSession dbses = new DatabaseSession(true)) {
			for(TGoodItemAndQuantity tGoodItemAndQuantity:goodItemAndQuantityList){
				int t = cartDao.getQuantity(dbses, userId, tGoodItemAndQuantity.getGoodId());
				if(t < tGoodItemAndQuantity.getQuantity())
					tGoodItemAndQuantity.setQuantity(t); 
				t -= tGoodItemAndQuantity.getQuantity();
				if(t == 0)
					cartDao.delete(dbses, userId, tGoodItemAndQuantity.getGoodId());
				else
					cartDao.updateQuantity(dbses, userId, tGoodItemAndQuantity.getGoodId(), tGoodItemAndQuantity.getQuantity());
			}
			if (!dbses.tryCommit()) {
				dbses.rollback();
			}
		}
	}
	
	@Override
	public void setCartItem(long userId, long goodId, int quantity)
			throws DatabaseException {
		
		try (DatabaseSession dbses = new DatabaseSession(true)) {
			
			if(quantity == 0)
				cartDao.delete(dbses, userId, goodId);
			else {
				int q = cartDao.getQuantity(dbses, userId, goodId);
				if(q == -1)
					cartDao.add(dbses, userId, goodId, quantity);
				else 
					cartDao.updateQuantity(dbses, userId, goodId, quantity);
			}
			
			if (!dbses.tryCommit()) {
				dbses.rollback();
			}
		}
	}

	@Override
	public List<CartItem> getCartItems(long userIdFilter, long limitStart,
			long limitLength, RefValue<Long> count) throws DatabaseException {
		
		try (DatabaseSession dbses = new DatabaseSession()) {
			if (count != null)
				count.setValue(cartDao.getCartItemsCount(dbses, userIdFilter));
			return cartDao.getCartItems(dbses, userIdFilter, limitStart, limitLength);
		}
		
	}

	@Override
	public List<TCartItemDetail> getCartItemsDetail(long userIdFilter, long limitStart,
			long limitLength, RefValue<Long> count) throws DatabaseException  {
		try (DatabaseSession dbses = new DatabaseSession()) {
			if (count != null)
				count.setValue(cartDao.getCartItemsCount(dbses, userIdFilter));
			
			List<CartItem> cartList=cartDao.getCartItems(dbses, userIdFilter, limitStart, limitLength);
			LinkedList<TCartItemDetail> list = new LinkedList<>();
			for (CartItem cartItem : cartList) {
				TCartItemDetail tCartItemDetail = new TCartItemDetail();
				tCartItemDetail.setCartItem(cartItem);
				tCartItemDetail.setGoodItem(goodDao.getGoodById(dbses, cartItem.getGoodId()));
				list.add(tCartItemDetail);
			}
			return list;
		}
	}
	
	@Override
	public long getCartItemsCount(long userIdFilter) throws DatabaseException {
		
		try (DatabaseSession dbses = new DatabaseSession()) {
			return cartDao.getCartItemsCount(dbses, userIdFilter);
		}
	}

	@Override
	public List<TCartItemDetail> transformToCartItemDetailList(long userId, List<TGoodItemAndQuantity> source) throws DatabaseException {
		
		try (DatabaseSession dbses = new DatabaseSession()) {
			LinkedList<TCartItemDetail> tCartItemDetail = new LinkedList<TCartItemDetail>();
			for(TGoodItemAndQuantity tGoodItemAndQuantity:source){
				CartItem cartItem = new CartItem();
				TCartItemDetail t = new TCartItemDetail();
				cartItem.setGoodId(tGoodItemAndQuantity.getGoodId());
				cartItem.setQuantity(tGoodItemAndQuantity.getQuantity());
				cartItem.setUserId(userId);
				GoodItem goodItem = goodDao.getGoodById(dbses, tGoodItemAndQuantity.getGoodId());
				if(goodItem != null){
					t.setCartItem(cartItem);
					t.setGoodItem(goodItem);
					tCartItemDetail.add(t);
				}
				
			}
			return tCartItemDetail;
		}
	}
	
	@Override
	public List<TGoodItemAndQuantity> transformToGoodItemAndQuantityList(List<TCartItemDetail> source) {
		
		LinkedList<TGoodItemAndQuantity> tGoodItemAndQuantity = new LinkedList<TGoodItemAndQuantity>();
		for(TCartItemDetail tCartItemDetail:source){
			TGoodItemAndQuantity t = new TGoodItemAndQuantity();
			t.setGoodId(tCartItemDetail.getGoodItem().getId());
			t.setQuantity(tCartItemDetail.getCartItem().getQuantity());
			tGoodItemAndQuantity.add(t);
		}
		return tGoodItemAndQuantity;
	}
	
}
